package xstring

import (
	"regexp"
	"strconv"
	"strings"
)

// 效验用户输入的规则符合用户名规则：英文大小写字母+数字
//
//	c	待效验的字符串
func CheckUsername(c string) bool {
	return regexp.MustCompile(`^[A-Za-z0-9]+$`).MatchString(c)
}

// 效验用户输入的规则是否符合密码规则
//
//	c	待效验的字符串
//	num	必须输入数字？
//	a	必须输入小写字母？
//	A	必须输入大写字母？
//	f	必须存在ANSI标识内的符号
func CheckPassword(c string, num, a, A, f bool) bool {
	if c == "" {
		return false
	}
	if num && !HasNumber(c) {
		return false
	}
	if a && !HasLetterLower(c) {
		return false
	}
	if A && !HasLetterUp(c) {
		return false
	}
	if f && !HasPunct(c) {
		return false
	}
	return true
}

// 手机号规则效验-国内手机号效验
//
//	c	待效验的手机号
//	fix	是否携带前缀
func CheckPhone(c string, fix bool) bool {
	if fix {
		return regexp.MustCompile(`^(\+?0?86\-?)?1[345789]\d{9}$`).MatchString(c)
	}
	return regexp.MustCompile(`^1[345789]\d{9}$`).MatchString(c)
}

// 邮箱格式效验
//
//	c	待效验的邮箱
func CheckEmail(c string) bool {
	return regexp.MustCompile(`^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$`).MatchString(c)
}

// 纯数字格式效验
//
//	c	待效验的数字
func CheckNumber(c string) bool {
	return regexp.MustCompile(`^[0-9]*$`).MatchString(c)
}

// 数字格式效验 - 验证通过正负数、小数、指数等
//
//	c	待效验的数字
func CheckFloat(c string) bool {
	return regexp.MustCompile(`^[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?$`).MatchString(c)
}

// 域名格式效验
//
//	c	待效验的字符串
func CheckDomain(c string) bool {
	return regexp.MustCompile(`^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?$`).MatchString(c)
}

// 域名格式效验
//
//	c	待效验的字符串
func CheckUrl(c string) bool {
	return regexp.MustCompile(`^[a-zA-z]+://[^\s]*$`).MatchString(c)
}

// 电话格式效验
//
//	c	待效验的字符串
func CheckTel(c string) bool {
	return regexp.MustCompile(`^(\d{3}-\d{7,8}|\d{4}-\d{7,8})(-\d+)?$`).MatchString(c)
}

// IPV4格式效验
//
//	c	待效验的字符串
func CheckIpv4(c string) bool {
	return regexp.MustCompile(`^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$`).MatchString(c)
}

// IPV6格式效验
//
//	c	待效验的字符串
func CheckIpv6(c string) bool {
	return regexp.MustCompile(`^([\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^::([\da-fA-F]{1,4}:){0,4}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:):([\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){2}:([\da-fA-F]{1,4}:){0,2}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){3}:([\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){4}:((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$|^([\da-fA-F]{1,4}:){7}[\da-fA-F]{1,4}$|^:((:[\da-fA-F]{1,4}){1,6}|:)$|^[\da-fA-F]{1,4}:((:[\da-fA-F]{1,4}){1,5}|:)$|^([\da-fA-F]{1,4}:){2}((:[\da-fA-F]{1,4}){1,4}|:)$|^([\da-fA-F]{1,4}:){3}((:[\da-fA-F]{1,4}){1,3}|:)$|^([\da-fA-F]{1,4}:){4}((:[\da-fA-F]{1,4}){1,2}|:)$|^([\da-fA-F]{1,4}:){5}:([\da-fA-F]{1,4})?$|^([\da-fA-F]{1,4}:){6}:$`).MatchString(c)
}

// 中国国民身份证号效验[15、18位身份证号码格式]
//
//	c	待效验的字符串
func CheckCardNo(c string) bool {
	if len(c) != 18 {
		return len(c) == 15 && CheckNumber(c)
	}
	nSum := 0
	weight := [17]int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
	valid_value := [11]byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
	for i := 0; i < len(c)-1; i++ {
		n, _ := strconv.Atoi(string(c[i]))
		nSum += n * weight[i]
	}
	mod := nSum % 11
	return valid_value[mod] == c[17]
}

// 日期格式效验
//
//	c	待效验的字符串
func CheckDate(c string) bool {
	return regexp.MustCompile(`^(\d{4}|\d{2})-\d{1,2}-\d{1,2}$`).MatchString(c)
}

// 时间格式效验
//
//	c	待效验的字符串
func CheckTime(c string) bool {
	return regexp.MustCompile(`^\d{1,2}:\d{1,2}:\d{1,2}$`).MatchString(c)
}

// 日期时间格式效验
//
//	c	待效验的字符串
func CheckDateTime(c string) bool {
	return regexp.MustCompile(`^(\d{4}|\d{2})-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}$`).MatchString(c)
}

// 指定正则格式效验
//
//	c	待效验的字符串
//	rep	正则表达式
func CheckRep(c, rep string) bool {
	return regexp.MustCompile(rep).MatchString(c)
}

// 版本检测，返回是否需要更新
//
//	min	最小版本号
//	now	当前版本号
func CheckVersion(min, now string) bool {
	if min == "" {
		return false
	}
	// 检测版本字符串格式是否正确，不正确则直接返回false
	if !CheckRep(min, `^[v|V]?\d(\.\d){1,}$`) {
		return false
	}
	if !CheckRep(now, `^[v|V]?\d(\.\d){1,}$`) {
		return false
	}
	// 去除版本号前缀v/V
	min = strings.ReplaceAll(min, "v", "")
	min = strings.ReplaceAll(min, "V", "")
	now = strings.ReplaceAll(now, "v", "")
	now = strings.ReplaceAll(now, "V", "")
	now_list := strings.Split(now, ".")
	min_list := strings.Split(min, ".")
	for i := 0; i < len(min_list); i++ {
		if len(now_list) <= i {
			continue
		}
		if ToInt(min_list[i]) > ToInt(now_list[i]) {
			return true
		}
	}
	return false
}
